NonZero ================= 查找输入张量中 **非零元素的位置索引**。 该算子按线性顺序遍历输入张量,对于满足“非零”判定条件的元素, 计算其在各维度上的索引,并顺序写入输出索引张量。 对于浮点类型,非零的判定标准为: .. math:: |x| > \epsilon 其中 :math:`\epsilon` 为平台定义的极小阈值(如 ``FLOAT_EPS``), 用于避免数值误差导致的误判。 输入: - **input** - 输入数据地址,按一维连续内存存储。 - **dim_strides** - 各维度步长数组,长度为 ``input_rank``, 用于将线性索引映射为多维索引。 - **shape** - 输入张量的形状数组,长度为 ``input_rank`` (当前实现中主要用于描述维度信息)。 - **input_rank** - 输入张量的维度数。 - **length** - 输入张量的元素总数。 - **core_mask** - 核掩码(仅适用于共享存储版本)。 输出: - **output** - 非零元素索引输出地址, 按 ``[non_zero_num, input_rank]`` 形式顺序存储。 - **non_zero_num** - 非零元素个数指针,函数执行结束后保存最终非零元素数量。 支持平台: ``FT78NE`` ``MT7004`` .. note:: - FT78NE 支持 ``fp32``、``fp64``、``int8``、``int16``、``int32``、``cplx64``、``cplx128`` 类型 - MT7004 支持 ``fp16``、``fp32``、``int16``、``int32``、``cplx64`` 类型 - 输出索引按照输入线性遍历顺序排列 - ``non_zero_num`` 在调用前需初始化为 0 **共享存储版本:** .. c:function:: void fp_nonzero_s(float* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) .. c:function:: void dp_nonzero_s(double* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) .. c:function:: void i8_nonzero_s(int8_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) .. c:function:: void i16_nonzero_s(int16_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) .. c:function:: void i32_nonzero_s(int32_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) .. c:function:: void c64_nonzero_s(cplx64* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) .. c:function:: void c128_nonzero_s(cplx128* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length, int core_mask) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 18-20 // FT78NE 示例 #include #include int main(int argc, char* argv[]) { float *input = (float *)0xA0000000; int *output = (int *)0xC0000000; int *non_zero_num = (int *)0xA1000000; int *dim_strides = (int *)0xA2000000; int *shape = (int *)0xA3000000; int input_rank = 3; int length = 1024; int core_mask = 0xff; non_zero_num[0] = 0; fp_nonzero_s(input, output, non_zero_num, dim_strides, shape, input_rank, length, core_mask); return 0; } **私有存储版本:** .. c:function:: void fp_nonzero_p(float* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) .. c:function:: void dp_nonzero_p(double* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) .. c:function:: void i8_nonzero_p(int8_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) .. c:function:: void i16_nonzero_p(int16_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) .. c:function:: void i32_nonzero_p(int32_t* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) .. c:function:: void c64_nonzero_p(cplx64* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) .. c:function:: void c128_nonzero_p(cplx128* input, int* output, int* non_zero_num, int* dim_strides, int* shape, int input_rank, int length) **C调用示例:** .. code-block:: c :linenos: :emphasize-lines: 17-18 // FT78NE 示例 #include #include int main(int argc, char* argv[]) { float *input = (float *)0x10810000; // L2 空间 int *output = (int *)0x10820000; int *non_zero_num = (int *)0x10830000; int *dim_strides = (int *)0x10840000; int *shape = (int *)0x10850000; int input_rank = 3; int length = 1024; non_zero_num[0] = 0; fp_nonzero_p(input, output, non_zero_num, dim_strides, shape, input_rank, length); return 0; }